package com.sunlee.app.api.service.impl;

import com.sunlee.app.api.constant.WxConstants;
import com.sunlee.app.api.entity.TokenEntity;
import com.sunlee.app.api.entity.dao.UserDao;
import com.sunlee.app.api.entity.dto.LoginDTO;
import com.sunlee.app.api.entity.dto.WxMpLoginDTO;
import com.sunlee.app.api.service.TokenService;
import com.sunlee.app.api.service.UserService;
import com.sunlee.app.api.service.WxMpApiService;
import com.sunlee.common.core.enums.ErrorCodeEnum;
import com.sunlee.common.core.exception.BusinessException;
import com.sunlee.common.core.service.impl.BaseServiceImpl;
import com.sunlee.common.service.enums.StatusEnum;
import com.sunlee.common.service.entity.CommonUserEntity;
import com.sunlee.app.api.entity.vo.UserInfoVO;
import com.sunlee.app.api.entity.vo.WeChatMiniAuthorizeVo;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl extends BaseServiceImpl<UserDao, CommonUserEntity> implements UserService {

    @Autowired
    private TokenService tokenService;

    @Autowired
    private WxMpApiService wxMpApiService;

    @Override
    public CommonUserEntity getByMobile(String mobile) {
        return baseDao.getUserByMobile(mobile);
    }

    @Override
    public CommonUserEntity getUserByUserId(Long userId) {
        return baseDao.getUserByUserId(userId);
    }

    @Override
    public CommonUserEntity getUserByOpenId(String mpOpenId) {
        return baseDao.getUserByOpenId(mpOpenId);
    }

    @Override
    public Map<String, Object> login(LoginDTO dto) {
        CommonUserEntity user = getByMobile(dto.getMobile());

        // 用户不存在
        if (user == null) {
            throw new BusinessException(ErrorCodeEnum.USER_NOT_EXIST);
        }

        // 密码错误
        if (!user.getPassword().equals(DigestUtils.sha256Hex(dto.getPassword()))) {
            throw new BusinessException(ErrorCodeEnum.USER_PASSWORD_WRONG);
        }

        // 黑名单账号
        if (user.getStatus() == StatusEnum.INVALID.getCode()) {
            throw new BusinessException(ErrorCodeEnum.USER_ACCOUNT_DISABLED);
        }

        // 获取登录token
        TokenEntity tokenEntity = tokenService.createToken(user.getId());

        Map<String, Object> map = new HashMap<>(4);
        map.put("token", tokenEntity.getToken());
        map.put("expire", tokenEntity.getExpireDate().getTime() - System.currentTimeMillis());

        return map;
    }

    @Override
    public UserInfoVO wxMpLogin(WxMpLoginDTO dto) {
        WeChatMiniAuthorizeVo weChatMiniAuthorizeVo = wxMpApiService.wxMpLoginByCode(dto.getCode());

        String openId = weChatMiniAuthorizeVo.getOpenId();
        CommonUserEntity user = getUserByOpenId(openId);

        // 头像为空，设置默认头像
        if (StringUtils.isBlank(dto.getHeadImg())) {
            dto.setHeadImg(WxConstants.DEFAULT_AVATAR_URL);
        }

        // 昵称为空，设置默认昵称
        if (StringUtils.isBlank(dto.getUserName())) {
            dto.setUserName(WxConstants.DEFAULT_NICKNAME);
        }


        if (user == null) {
            // 不存在，注册
            user = new CommonUserEntity();
            user.setUsername(dto.getUserName());
            user.setHeadImg(dto.getHeadImg());
            user.setMpOpenId(openId);
            user.setCreateDate(new Date());
            user.setStatus(StatusEnum.VALID.getCode());
            insertOwn(user);
        } else {
            // 存在，更新数据

            // 判断是否更新头像
            if (StringUtils.isBlank(user.getHeadImg()) || !WxConstants.DEFAULT_AVATAR_URL.equals(dto.getHeadImg())) {
                user.setHeadImg(dto.getHeadImg());
            }

            // 判断是否更新昵称
            if (StringUtils.isBlank(user.getUsername()) || !WxConstants.DEFAULT_NICKNAME.equals(dto.getUserName())) {
                user.setUsername(dto.getUserName());
            }

            updateByIdOwn(user);
        }

        // 创建登录token
        TokenEntity tokenEntity = tokenService.createToken(user.getId());

        UserInfoVO userInfoVO = new UserInfoVO();
        userInfoVO.setUserId(user.getId());
        userInfoVO.setHeadImg(user.getHeadImg());
        userInfoVO.setUserName(user.getUsername());
        userInfoVO.setToken(tokenEntity.getToken());
        userInfoVO.setExpire(tokenEntity.getExpireDate().getTime() - System.currentTimeMillis());

        return userInfoVO;
    }

}